package com.whc.gulimall.product.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.whc.common.constant.ProductConstant;
import com.whc.common.utils.PageUtils;
import com.whc.common.utils.Query;
import com.whc.gulimall.product.dao.AttrAttrgroupRelationDao;
import com.whc.gulimall.product.dao.AttrDao;
import com.whc.gulimall.product.dao.AttrGroupDao;
import com.whc.gulimall.product.dao.CategoryDao;
import com.whc.gulimall.product.entity.AttrAttrgroupRelationEntity;
import com.whc.gulimall.product.entity.AttrEntity;
import com.whc.gulimall.product.entity.AttrGroupEntity;
import com.whc.gulimall.product.entity.CategoryEntity;
import com.whc.gulimall.product.service.AttrAttrgroupRelationService;
import com.whc.gulimall.product.service.AttrGroupService;
import com.whc.gulimall.product.service.AttrService;
import com.whc.gulimall.product.vo.AttrAttrGroupRelationVo;
import com.whc.gulimall.product.vo.AttrGroupWithAttrsVo;
import com.whc.gulimall.product.vo.SpuItemAttrGroup;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Service("attrGroupService")
public class AttrGroupServiceImpl extends ServiceImpl<AttrGroupDao, AttrGroupEntity> implements AttrGroupService {

    /**
     * 商品三级分类 Dao
     */
    @Resource
    private CategoryDao categoryDao;

    /**
     * 商品属性 Dao
     */
    @Resource
    private AttrDao attrDao;

    /**
     * 属性&属性分组关联 Dao
     */
    @Resource
    private AttrAttrgroupRelationDao attrAttrgroupRelationDao;

    /**
     * 属性分组 Dao
     */
    @Resource
    private AttrGroupDao attrGroupDao;

    /**
     * 商品属性 Service
     */
    @Resource
    private AttrService attrService;

    /**
     * 属性&属性分组关联 Service
     */
    @Resource
    private AttrAttrgroupRelationService attrAttrgroupRelationService;


    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<AttrGroupEntity> page = this.page(
                new Query<AttrGroupEntity>().getPage(params),
                new QueryWrapper<AttrGroupEntity>()
        );

        return new PageUtils(page);
    }

    /**
     * 获取分页列表
     *
     * @param params 参数
     * @param catId  分类id
     * @return 封装好的分页数据
     */
    @Override
    public PageUtils queryPage(Map<String, Object> params, Long catId) {
        // 获取查询条件
        String key = (String) params.get("key");
        QueryWrapper<AttrGroupEntity> wrapper = new QueryWrapper<>();
        // 根据查询条件设置wrapper查询
        if (StringUtils.hasText(key)) {
            wrapper.and((obj) -> obj.eq("attr_group_id", key).or().like("attr_group_name", key));
        }
        // 如果不为0代表根据分类id查询
        if (!catId.equals(0L)) {
            wrapper.eq("catelog_id", catId);
        }
        IPage<AttrGroupEntity> page = this.page(new Query<AttrGroupEntity>().getPage(params), wrapper);
        return new PageUtils(page);
    }

    /**
     * 通过id获取到分组属性
     *
     * @param attrGroupId 分组id
     * @return 获取数据
     */
    @Override
    public AttrGroupEntity getInfoById(Long attrGroupId) {
        // 获取到分组属性
        AttrGroupEntity attrGroupEntity = baseMapper.selectById(attrGroupId);

        // 获取到三级分类id
        Long catelogId = attrGroupEntity.getCatelogId();
        QueryWrapper<CategoryEntity> categoryWrapper = new QueryWrapper<>();
        categoryWrapper.eq("cat_id", catelogId);
        CategoryEntity categoryEntity = categoryDao.selectOne(categoryWrapper);

        // 获取到二级分类id
        Long parentCid = categoryEntity.getParentCid();
        QueryWrapper<CategoryEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("cat_id", parentCid);
        CategoryEntity categoryEntity1 = categoryDao.selectOne(wrapper);

        // 获取到一级分类id
        Long parentCid1 = categoryEntity1.getParentCid();
        QueryWrapper<CategoryEntity> categoryEntityQueryWrapper = new QueryWrapper<>();
        categoryEntityQueryWrapper.eq("cat_id", parentCid1);
        CategoryEntity categoryEntity2 = categoryDao.selectOne(categoryEntityQueryWrapper);

        // 封装数据
        ArrayList<Long> longs = new ArrayList<>();
        longs.add(categoryEntity2.getCatId());
        longs.add(categoryEntity1.getCatId());
        longs.add(catelogId);
        attrGroupEntity.setCatelogPath(longs);
        return attrGroupEntity;
    }

    /**
     * 根据attrId和attrGroupId移除数据
     *
     * @param deleteVos 封装好的数据集合
     */
    @Override
    public void removeAttrGroupByAttrIdsAndAttrGroupIds(List<AttrAttrGroupRelationVo> deleteVos) {
        // 判空
        if (CollUtil.isEmpty(deleteVos)) {
            return;
        }
        // 获取属性id集合
        List<Long> attrIds = deleteVos.stream()
                .map(AttrAttrGroupRelationVo::getAttrId).collect(Collectors.toList());
        // 判空
        if (CollUtil.isNotEmpty(attrIds)) {
            attrAttrgroupRelationDao.delete(new QueryWrapper<AttrAttrgroupRelationEntity>()
                    .eq("attr_group_id", deleteVos.get(0).getAttrGroupId())
                    .in("attr_id", attrIds));
        }
    }

    /**
     * 获取属性分组没有关联的其他属性
     *
     * @param params      参数
     * @param attrgroupId 分组id
     * @return 分页数据
     */
    @Override
    public PageUtils getNoRelationAttr(Map<String, Object> params, Long attrgroupId) {
        /*
        思路：
        目前有的是attrgourpId，要获取到的是同一个分类下的别的分组没有关联上的属性
        那么首先是需要去pms_attr_group表中查到attr_group_id对应的catelog_id
        然后拿着catelog_id去pms_attr查出同一catelog_id的attrId
         */
        // 获取所属分类
        AttrGroupEntity attrGroupEntity = baseMapper.selectById(attrgroupId);
        QueryWrapper<AttrEntity> wrapper = new QueryWrapper<AttrEntity>()
                .eq("attr_type", ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode());
        if (attrGroupEntity != null) {
            Long catelogId = attrGroupEntity.getCatelogId();
            // 根据分类id获取到在同一个分类下的属性
            // 只能关联别的分组没有关联的属性
            List<AttrGroupEntity> attrGroupEntities = attrGroupDao.selectList(new QueryWrapper<AttrGroupEntity>()
                    .eq("catelog_id", catelogId));
            if (CollUtil.isNotEmpty(attrGroupEntities)) {
                // 获取到分组id列表
                List<Long> attrGroupIds = attrGroupEntities.stream().map(AttrGroupEntity::getAttrGroupId)
                        .collect(Collectors.toList());
                // 判空
                if (CollUtil.isNotEmpty(attrGroupIds)) {
                    List<AttrAttrgroupRelationEntity> attrgroupRelationEntities = attrAttrgroupRelationDao
                            .selectList(new QueryWrapper<AttrAttrgroupRelationEntity>()
                                    .in("attr_group_id", attrGroupIds));
                    // 判空
                    if (CollUtil.isNotEmpty(attrgroupRelationEntities)) {
                        // 获取到已经在关联表中的attrIds，那么通过notIn(attrIds)就可以得到在同一分类下的不同分组为关联的属性
                        List<Long> attrIds = attrgroupRelationEntities.stream()
                                .map(AttrAttrgroupRelationEntity::getAttrId).collect(Collectors.toList());
                        // 判空
                        if (CollUtil.isNotEmpty(attrIds)) {
                            wrapper.eq("catelog_id", catelogId).notIn("attr_id", attrIds);
                            // 根据条件查询
                            String key = (String) params.get("key");
                            if (StrUtil.isNotBlank(key)) {
                                wrapper.and(obj -> obj.eq("attr_id", key).or().like("attr_name", key));
                            }
                        }
                    }
                }
            }
        }
        IPage<AttrEntity> page = attrService.page(new Query<AttrEntity>().getPage(params), wrapper);
        return new PageUtils(page);
    }

    /**
     * 添加属性与分组关联关系
     *
     * @param relationVos 关系列表
     */
    @Override
    public void saveAttrRelation(List<AttrAttrGroupRelationVo> relationVos) {
        // 判空
        if (CollUtil.isNotEmpty(relationVos)) {
            List<AttrAttrgroupRelationEntity> relationEntityList = relationVos.stream().map(item -> {
                AttrAttrgroupRelationEntity entity = new AttrAttrgroupRelationEntity();
                entity.setAttrGroupId(item.getAttrGroupId());
                entity.setAttrId(item.getAttrId());
                return entity;
            }).collect(Collectors.toList());
            if (CollUtil.isNotEmpty(relationEntityList)) {
                attrAttrgroupRelationService.saveBatch(relationEntityList);
            }
        }
    }

    /**
     * 获取分类下所有分组&关联属性
     *
     * @param catelogId 三级分类id
     * @return vo
     */
    @Override
    public List<AttrGroupWithAttrsVo> getAttrGroupWithAttrByCatelogId(Long catelogId) {
        // 获取属性分组列表
        List<AttrGroupEntity> attrGroupEntities = baseMapper.selectList(new QueryWrapper<AttrGroupEntity>()
                .eq("catelog_id", catelogId));
        // 判空
        if (CollUtil.isNotEmpty(attrGroupEntities)) {
            // 获取分组id列表
            List<Long> attrGroupIds = attrGroupEntities.stream().map(AttrGroupEntity::getAttrGroupId)
                    .collect(Collectors.toList());
            // 判空
            if (CollUtil.isNotEmpty(attrGroupIds)) {
                // 获取所有属性
                List<AttrEntity> attrEntities = attrGroupDao.listAttrsByAttrGroupIds(attrGroupIds);
                // 判空
                if (CollUtil.isNotEmpty(attrEntities)) {
                    // 通过attrGroupId分组
                    Map<Long, List<AttrEntity>> collect = attrEntities.stream()
                            .collect(Collectors.groupingBy(AttrEntity::getAttrGroupId));
                    // 判空
                    if (CollUtil.isNotEmpty(collect)) {
                        // 通过attrGroupId获取对应下的attr
                        return attrGroupEntities.stream().map(item -> {
                            AttrGroupWithAttrsVo attrGroupWithAttrsVo = new AttrGroupWithAttrsVo();
                            BeanUtil.copyProperties(item, attrGroupWithAttrsVo);
                            List<AttrEntity> attrList = collect.get(item.getAttrGroupId());
                            if (CollUtil.isNotEmpty(attrList)) {
                                attrGroupWithAttrsVo.setAttrs(attrList);
                            }
                            return attrGroupWithAttrsVo;
                        }).collect(Collectors.toList());
                    }
                }
            }
            return BeanUtil.copyToList(attrGroupEntities, AttrGroupWithAttrsVo.class);
        }
        return null;
    }

    /**
     * 根据分组id删除分组
     *
     * @param attrGroupIds id列表
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteAttrGroupByIds(List<Long> attrGroupIds) {
        if (CollUtil.isNotEmpty(attrGroupIds)) {
            // 批量删除分组信息
            removeByIds(attrGroupIds);
            // 批量删除属性id
            List<Long> attrIds = attrAttrgroupRelationDao.listAttrIdsByAttrGroupIds(attrGroupIds);
            if (CollUtil.isNotEmpty(attrIds)) {
                attrService.removeByIds(attrIds);
            }
        }
    }

    /**
     * 通过分类id和spuId获取属性规格参数列表
     *
     * @param catalogId 分类id
     * @param spuId     spuId
     * @return 属性规格参数列表
     */
    @Override
    public List<SpuItemAttrGroup> listAttrGroupByCatelogAndSpuId(Long catalogId, Long spuId) {
        return baseMapper.listAttrGroupByCatelogAndSpuId(catalogId, spuId);
    }
}
